package com.hsgene.gateway.filter;

import com.hsgene.common.util.basic.JsonUtils;
import com.hsgene.common.util.exception.CommonErrorCode;
import com.hsgene.common.util.result.ApiResult;
import com.hsgene.common.util.result.NullObject;
import com.hsgene.gateway.support.ClientRequestValidationSupport;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

/**
 * 权限验证过滤器
 *
 * @author wangbing
 * @version 1.0, 2018/6/20
 */
@Component
public class MsValidationFilter extends ZuulFilter {

    private final static Logger LOGGER = LoggerFactory.getLogger(MsValidationFilter.class);

    @Resource
    private ClientRequestValidationSupport clientRequestValidationSupport;

    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 5;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        try {
            ApiResult<NullObject> result = clientRequestValidationSupport.validate(ctx.getRequest());
            String validationResult = "客户端请求验证结果：";
            validationResult += result.isSucc() ? "验证通过，可以访问！" : "验证拒绝，" + result.getDesc();
            if (result.isSucc()) {
                LOGGER.info(validationResult);
            } else {
                LOGGER.error(validationResult);
                responseFail(ctx, result);
            }
        } catch (Exception e) {
            LOGGER.error("ValidationFilter Exception:", e);
            responseFail(ctx, ApiResult.fail(CommonErrorCode.GATEWAY_SERVICE_EXCEPTION));
        }
        return null;
    }

    /**
     * 失败返回
     *
     * @param ctx        请求上下文
     * @param failResult 失败信息
     */
    private void responseFail(RequestContext ctx, ApiResult failResult) {
        ctx.setSendZuulResponse(false);
        ctx.set("isSuccess", false);
        HttpServletResponse response = ctx.getResponse();
        response.setHeader("Content-type", "application/json;charset=UTF-8");
        ctx.setResponseBody(JsonUtils.objectToJsonIgnoreNull(failResult));
    }
}
